package com.svms.vehicle;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.StringUtils;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventQueues;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import com.svms.service.constants.Constants;
import com.svms.service.constants.SvmsStatusCodes;
import com.svms.service.vo.TransportVO;
import com.svms.service.vo.VehicleVO;
import com.svms.transport.TransportListModelItemRender;
import com.svms.utils.SvmsMessageUtils;
import com.svms.utils.SvmsWindowUtils;
import com.svms.web.factory.SvmsWebFactory;

public class VehicleDialogueCtrl extends GenericForwardComposer implements
		Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	// *********************************************//

	private Window window_vehicle_dialogue;

	private Textbox txb_VehiceNumber;
	private Textbox txb_VehicleModel;
	private Listbox cbb_Transport;
	private Datebox dtb_Frm47;
	private Datebox dtb_NC;
	private Datebox dtb_FC;
	private Datebox dtb_Insurance;
	private Datebox dtb_Tax;

	private Button btn_add_vehicle;
	private Button btn_delete_vehicle;
	private Button btn_edit_vehicle;
	private Button btn_save_vehicle;
	private Button btn_cancle;
	private Button btn_close;

	private ListModelList<TransportVO> lst_model_transport;

	// *********************************************//

	private ManageVehicleCtrl manageVehicleCtrl;

	private VehicleVO vehicleVO;
	private VehicleVO oldVehicleVO;

	public VehicleVO getVehicleVO() {
		return vehicleVO;
	}

	public void setVehicleVO(VehicleVO vehicleVO) {
		this.vehicleVO = vehicleVO;
	}

	public VehicleVO getOldVehicleVO() {
		return oldVehicleVO;
	}

	public void setOldVehicleVO(VehicleVO oldVehicleVO) {
		this.oldVehicleVO = oldVehicleVO;
	}

	public VehicleDialogueCtrl() {
		super();
	}

	/**
	 * Operation to be performed on load of the window.
	 * 
	 * @param event
	 * @throws Exception
	 */
	public void onCreate$window_vehicle_dialogue(Event event) throws Exception {

		Map<String, Object> args = SvmsWindowUtils.getCreationArgsMap(event);

		// vehicleVO = (VehicleVO) args.get("selectedVehicle");
		VehicleVO selectedVehicle = (VehicleVO) args.get("selectedVehicle");

		setVehicleVO((VehicleVO) SerializationUtils.clone(selectedVehicle));

		manageVehicleCtrl = (ManageVehicleCtrl) args.get("vehicleListCtrl");

		if (getVehicleVO() == null) {
			// Which means edit in progress. So enable fields to edit
			enableFields();
			loadAddEditScenarioButtons();
			newCustomerMapping();
		} else {
			// oldVehicleVO = (VehicleVO) SerializationUtils.clone(vehicleVO);
			setOldVehicleVO((VehicleVO) SerializationUtils
					.clone(getVehicleVO()));
			disableFields();
			loadDefalutScenarioButtons();
			writeBeanToDialogue(getOldVehicleVO());
		}

	}

	/**
	 * New customer is create. i.e empty values are set to the fields in the
	 * dialogue box
	 */
	private void newCustomerMapping() {
		setVehicleVO(new VehicleVO());
		getVehicleVO().setVehicleDocuments(new HashMap<String, Date>());
		writeBeanToDialogue(getVehicleVO());
	}

	/**
	 * Operation to be performed on click of add vehicle button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_add_vehicle(Event event) {
		setOldVehicleVO(null);
		newCustomerMapping();
		enableFields();
		loadAddEditScenarioButtons();
	}

	/**
	 * Operation to be performed on click of edit button. It will
	 * loadAddEditScenarioButtons and enables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_edit_vehicle(Event event) {
		enableFields();
		loadAddEditScenarioButtons();
	}

	/**
	 * Operation to be performed on click of cancel button. It will
	 * loadDefalutScenarioButtons and disables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_cancle(Event event) {
		writeBeanToDialogue(getOldVehicleVO());
		setVehicleVO(getOldVehicleVO());
		disableFields();
		loadDefalutScenarioButtons();
	}

	public void onClick$btn_close(Event event) {
		setVehicleVO(getOldVehicleVO());
		window_vehicle_dialogue.detach();
	}

	/**
	 * Operation to be performed on click of save button. It performs the save
	 * operation. It will loadDefalutScenarioButtons and disables all editable
	 * fields on successful save
	 * 
	 * @param event
	 */
	public void onClick$btn_save_vehicle(Event event) {
		writeDialogueToBean();
		doSave();
	}

	/**
	 * Save operation by calling save method from service
	 */
	private void doSave() {
		writeDialogueToBean();
		VehicleVO vehicleVO = null;
		if (StringUtils.isBlank(getVehicleVO().getVehicleId())) {
			vehicleVO = SvmsWebFactory.vehicleService().insertNewVehicle(
					getVehicleVO());
		} else {
			vehicleVO = SvmsWebFactory.vehicleService().editVehicle(
					getVehicleVO());
		}

		if (vehicleVO.getResultCode().getErrorDetails().size() > 0) {
			SvmsMessageUtils.showErrorMessageFromLable(vehicleVO
					.getResultCode().getErrorDetails());
			// writeBeanToDialogue(oldVehicleVO);
			return;
		} else {

			if (manageVehicleCtrl.getLstbx_vehicles() != null) {

				// now synchronize the customer listBox
				final ListModelList lml = (ListModelList) manageVehicleCtrl
						.getLstbx_vehicles().getListModel();

				// Check if the customer object is new or updated
				// -1 means that the obj is not in the list, so it's new.
				if (lml.indexOf(getOldVehicleVO()) == -1) {
					lml.add(getVehicleVO());
					System.out.println("Add vehicle to main vehicle list");
					setOldVehicleVO(getVehicleVO());
				} else {
					lml.set(lml.indexOf(getOldVehicleVO()), getVehicleVO());
					System.out.println("save vehicle to main vehicle list");
					setOldVehicleVO(getVehicleVO());
				}

				System.out.println("Event vehicleAlertEventQueue Publicshed");
				EventQueues.lookup("vehicleAlertEventQueue",
						EventQueues.DESKTOP, true).publish(new Event("onVehicleListChange",null));
			}
			SvmsMessageUtils
					.showSuccessMessage("Vehicle Was successfully saved to the system");
			disableFields();
			loadDefalutScenarioButtons();
		}

		// call from cusromerList then synchronize the customers listBox

	}

	/**
	 * Operation to be performed on click of cancel button. It will
	 * loadDefalutScenarioButtons and disables all editable fields
	 * 
	 * @param event
	 */
	public void onClick$btn_delete_vehicle(Event event) {

		writeDialogueToBean();

		if (vehicleVO != null && vehicleVO.getVehicleId() != null) {
			VehicleVO vehicleVO = SvmsWebFactory.vehicleService()
					.deleteVehicle(getVehicleVO());
		} else {
			SvmsMessageUtils
					.showErrorMessageFromLable(SvmsStatusCodes.SELECT_VEHICLE_TO_DELETE);
			return;
		}

		if (vehicleVO.getResultCode().getErrorDetails().size() > 0) {
			SvmsMessageUtils.showErrorMessageFromLable(vehicleVO
					.getResultCode().getErrorDetails());
			return;
		} else {
			SvmsMessageUtils
					.showSuccessMessage("Vehicle Was successfully deleted from the System");
			disableFields();
			loadDefalutScenarioButtons();
		}

		// call from cusromerList then synchronize the customers listBox
		if (manageVehicleCtrl.getLstbx_vehicles() != null) {

			// now synchronize the customer listBox
			final ListModelList lml = (ListModelList) manageVehicleCtrl
					.getLstbx_vehicles().getListModel();

			// Check if the customer object is new or updated
			// -1 means that the obj is not in the list, so it's new.
			if (lml.indexOf(getOldVehicleVO()) == -1) {
				System.out.println("Vehicle not present in main vehicle list");
			} else {
				lml.remove(getOldVehicleVO());
				System.out.println("Removed vehicle from main vehicle list");
			}

		}
		window_vehicle_dialogue.detach();
	}

	/**
	 * To copy the contents form the individual fields in dialogue box to
	 * service for processing
	 * 
	 * @param vehicleVO
	 */
	private void writeDialogueToBean() {

		vehicleVO.setVehicleNumber(txb_VehiceNumber.getValue());
		vehicleVO.setModel(txb_VehicleModel.getValue());
		vehicleVO.setDistanceTraveled("0");

		Map<String, Date> vehcileDocuments = new HashMap<String, Date>();
		vehcileDocuments.put(Constants.FORM47_TD, dtb_Frm47.getValue());
		vehcileDocuments.put(Constants.FC_TD, dtb_FC.getValue());
		vehcileDocuments.put(Constants.NC_TD, dtb_NC.getValue());
		vehcileDocuments.put(Constants.INSURANCE_TD, dtb_Insurance.getValue());
		vehcileDocuments.put(Constants.TAX_TD, dtb_Tax.getValue());
		vehicleVO.setVehicleDocuments(vehcileDocuments);

		Listitem listitem = cbb_Transport.getSelectedItem();
		if (listitem != null) {
			vehicleVO.setTransport((TransportVO) listitem
					.getAttribute("selectedTransport"));
		}

	}

	/**
	 * To copy the contents form the VO to dialogue box. Individual mapping of
	 * values needs to be done.
	 * 
	 * @param vehicleVO
	 */
	private void writeBeanToDialogue(VehicleVO vehicleVO) {

		// To populate the transport dropdown with all the values in TransporDB

		ListModelList<TransportVO> list = new ListModelList<TransportVO>(
				SvmsWebFactory.transportService().getTransportList());
		if (vehicleVO != null) {
			cbb_Transport.setModel(list);
			cbb_Transport.setItemRenderer(new TransportListModelItemRender());

			txb_VehiceNumber.setValue(vehicleVO.getVehicleNumber());
			txb_VehicleModel.setValue(vehicleVO.getModel());
			dtb_Frm47.setValue(vehicleVO.getVehicleDocuments().get(
					Constants.FORM47_TD));
			dtb_NC.setValue(vehicleVO.getVehicleDocuments()
					.get(Constants.NC_TD));
			dtb_FC.setValue(vehicleVO.getVehicleDocuments()
					.get(Constants.FC_TD));
			dtb_Insurance.setValue(vehicleVO.getVehicleDocuments().get(
					Constants.INSURANCE_TD));
			dtb_Tax.setValue(vehicleVO.getVehicleDocuments().get(
					Constants.TAX_TD));
			cbb_Transport.setSelectedIndex(list.indexOf(vehicleVO
					.getTransport()));
		}
	}

	/**
	 * Enables all the text box so that it can be edited
	 */
	private void enableFields() {
		txb_VehiceNumber.setDisabled(false);
		txb_VehicleModel.setDisabled(false);
		cbb_Transport.setDisabled(false);
		dtb_Frm47.setDisabled(false);
		dtb_Frm47.setFormat("dd-MMM-yyyy");
		dtb_NC.setDisabled(false);
		dtb_NC.setFormat("dd-MMM-yyyy");
		dtb_FC.setDisabled(false);
		dtb_FC.setFormat("dd-MMM-yyyy");
		dtb_Insurance.setDisabled(false);
		dtb_Insurance.setFormat("dd-MMM-yyyy");
		dtb_Tax.setDisabled(false);
		dtb_Tax.setFormat("dd-MMM-yyyy");
	}

	/**
	 * Disables all the text box so that it cannot edited
	 */
	private void disableFields() {
		txb_VehiceNumber.setDisabled(true);
		txb_VehicleModel.setDisabled(true);
		cbb_Transport.setDisabled(true);
		dtb_Frm47.setDisabled(true);
		dtb_NC.setDisabled(true);
		dtb_FC.setDisabled(true);
		dtb_Insurance.setDisabled(true);
		dtb_Tax.setDisabled(true);
	}

	/**
	 * Will load ADD VEHCILE scenario CURD buttons.
	 * 
	 */
	private void loadAddEditScenarioButtons() {
		btn_add_vehicle.setDisabled(true);
		btn_delete_vehicle.setDisabled(true);
		btn_edit_vehicle.setDisabled(true);
		btn_save_vehicle.setDisabled(false);
		btn_cancle.setDisabled(false);
		btn_close.setDisabled(false);
	}

	/**
	 * Will load defalut CURD buttons. Is same for DEFALUT, SAVE, DISCARD
	 */
	private void loadDefalutScenarioButtons() {
		btn_add_vehicle.setDisabled(false);
		btn_delete_vehicle.setDisabled(false);
		btn_edit_vehicle.setDisabled(false);
		btn_save_vehicle.setDisabled(true);
		btn_cancle.setDisabled(true);
		btn_close.setDisabled(false);
	}

}
